home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 March - Disc 1 / Macworld (1999-03) (Disk 1).dmg / Shareware World / Utilities / Text Processing / Alpha / Tcl / Menus / electricMenu.tcl < prev    next >
Encoding:
Text File  |  1998-11-15  |  10.5 KB  |  342 lines  |  [TEXT/ALFA]

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #    Vince's    Additions -    an extension package for Alpha
  4.  # 
  5.  #    FILE: "electricMenu.tcl"
  6.  #                     created: 8/3/96 {1:34:42 pm}    
  7.  #                  last update: 5/8/98 {11:02:18 pm}    
  8.  #    Author:    Vince Darley
  9.  #    E-mail:    <darley@fas.harvard.edu>
  10.  #      mail:    Division of    Applied    Sciences, Harvard University
  11.  #            Oxford Street, Cambridge MA    02138, USA
  12.  #       www:    <http://www.fas.harvard.edu/~darley/>
  13.  #    
  14.  #    Handles the electric menu.
  15.  #    
  16.  # ###################################################################
  17.  ##
  18.  
  19. alpha::menu electricMenu 1.3.2 global "•280" {
  20.     # so we don't use the standard proc to build this menu.
  21.     menu::buildProc elec "#"
  22.     namespace eval elec {}
  23. } { 
  24.     elec::rebuildElectricMenu 
  25. } {
  26. } maintainer {
  27.     "Vince Darley" darley@fas.harvard.edu <http://www.fas.harvard.edu/~darley/>
  28. } uninstall this-file help {file "ElecCompletions Help"}
  29.  
  30. alpha::package require elecCompletions 9.0
  31.  
  32. lunion flagPrefs(Electrics) showElectricsInMenu putTemplatesInMainMenu \
  33.   showElectricKeysInMenu addTemplateManipulators 
  34.  
  35. eval lunion elec::MenuTemplates ""
  36. lunion elec::LicenseTemplates \
  37.   "none" "copyrightNotice" "allRightsReserved" "allRightsReservedOrg" \
  38.   "seeFileLicenseTerms" "gnuPublicLicense"
  39.  
  40. # register this proc to be called whenever the mode changes.
  41. hook::register changeMode elec::rebuildElectricMenu
  42. hook::register electricBindings elec::BindingsChanged
  43. # Show mode-dependent electric completions in menu; i.e. include in the
  44. # menu all items which when typed, followed by cmd-Tab, will complete
  45. # into some command.
  46. newPref flag showElectricsInMenu 1 global elec::clearAndBuildElectricMenu
  47. # Add the list of key-bindings to the bottom of the menu.  These are
  48. # the items you may edit with Global->SpecialKeys, which are used to
  49. # trigger Completions, Expansions, Template Stop movement etc.
  50. newPref flag showElectricKeysInMenu 1 global elec::clearAndBuildElectricMenu
  51. # Add a couple of items to let you create or delete new templates
  52. newPref flag addTemplateManipulators 0 global elec::clearAndBuildElectricMenu
  53. # Put all the templates into the main menu rather than in a submenu
  54. newPref flag putTemplatesInMainMenu 0 global elec::clearAndBuildElectricMenu
  55. proc elec::BindingsChanged {} {
  56.     global showElectricKeysInMenu
  57.     if $showElectricKeysInMenu {elec::clearAndBuildElectricMenu}
  58. }
  59.  
  60. proc elec::getMenuBindings {} {
  61.     global showElectricKeysInMenu keys::specialBindings
  62.     # get menu items which represent the current bindings
  63.     if $showElectricKeysInMenu {
  64.         return [menu::bindingsFromArray keys::specialBindings]
  65.     } else {
  66.         return ""
  67.     }
  68. }
  69.  
  70. ## 
  71.  # -------------------------------------------------------------------------
  72.  # 
  73.  # "elec::rebuildElectricMenu" --
  74.  # 
  75.  #  Reasonably clever procedure to construct a Template menu from the
  76.  #  ${mode}electrics array on the fly.  Works with 'ensemble' completions,
  77.  #  putting them in submenus (that's why the code is a little messy; I
  78.  #  couldn't dream up a neater method).
  79.  # -------------------------------------------------------------------------
  80.  ##
  81. proc elec::rebuildElectricMenu {args} {
  82.     set mmode [modeALike]
  83.     if {[cache::exists elecMenu::elec-${mmode}]} {
  84.     cache::read elecMenu::elec-${mmode}
  85.     message ""
  86.     } else {        
  87.     global ${mmode}electrics electricMenu showElectricsInMenu
  88.     
  89.     set m [list Menu -n ${electricMenu} -m -p elec::MenuProc]
  90.     # make the menu of electrics if desired
  91.     if {$showElectricsInMenu && [array exists ${mmode}electrics]} {
  92.         set items [lsort [array names ${mmode}electrics]]
  93.         # remove all contractions
  94.         set items [lremove -all -glob $items "*'*"]
  95.         # remove something else (I've forgotten what!)
  96.         regsub -all { [^ ]*\*[^ ]*} " $items " { } items
  97.         set c [set items]
  98.         while {[regexp {\{(\w+) \w+\}} $c all pref]} {
  99.         set c [string range $c [expr {[string last "\{$pref " $c] +2}] end]
  100.         lappend got $pref
  101.         }
  102.         if {[info exists got]} {
  103.         foreach pref $got {
  104.             regsub "(\{${pref} \\w+\} )+" $items \
  105.               "\{Menu -n \"   ${pref}\" -m -p elec::MenuProc \{\\0\}\} " items
  106.         }
  107.         }    
  108.     } else {
  109.         set items ""
  110.     }
  111.     # make the whole menu
  112.     set items [concat [elec::makeTemplatesMenu $mmode] $items "(-" \
  113.       [elec::getMenuBindings] [list "Add Electric Item"] ]
  114.     global addTemplateManipulators
  115.     if ${addTemplateManipulators} {
  116.         lappend items "Grab Selection" "Insert Old Selection" \
  117.           "Insert In Lines"
  118.     }
  119.     lappend items "Clear Elec Menu Cache"
  120.     lappend m $items
  121.     cache::add elecMenu::elec-${mmode} variable m
  122.     }
  123.     eval $m
  124. }
  125.  
  126. proc elec::clearAndBuildElectricMenu {args} {
  127.     cache::deletePat elecMenu::elec-*
  128.     elec::rebuildElectricMenu
  129. }
  130.  
  131. proc elec::makeTemplatesMenu {mmode} {
  132.     # make the templates submenu
  133.     global ${mmode}Templates elec::MenuTemplates \
  134.         elec::LicenseTemplates menu::additions putTemplatesInMainMenu
  135.     set m ${elec::MenuTemplates}
  136.     if [info exists ${mmode}Templates] {
  137.         set m [concat $m [set ${mmode}Templates]]
  138.     }
  139.     set m [lsort $m]
  140.     eval lappend m "(-" [lsort [lremove ${elec::LicenseTemplates} "none"]]
  141.     if [info exists menu::additions(elec)] {
  142.         foreach i [set menu::additions(elec)] {
  143.             eval lappend m "(-" [lrange $i 2 end]
  144.         }
  145.     }
  146.     lappend m "(-" "addTemplateItem" "removeTemplateItem"
  147.     if $putTemplatesInMainMenu {
  148.         foreach i $m {
  149.             if {[lindex $i 0] == "Menu"} {
  150.                 lappend ret $i
  151.             } else {
  152.                 lappend ret "[quote::Prettify $i] "
  153.             }
  154.         }
  155.         return $ret
  156.     } else {    
  157.         return [list "Menu -n Templates -p elec::userTemplates [list $m]"]
  158.     }
  159.     
  160. }
  161.  
  162. proc elec::rebuildTemplatesMenu { {mmode ""} } {
  163.     if {$mmode == ""} {set mmode [modeALike]}
  164.     eval [lindex [elec::makeTemplatesMenu $mmode] 0]
  165. }
  166.  
  167. proc elec::userTemplates {menu item} {
  168.     set t [file::$item]    
  169.     if {$t != ""} {
  170.         elec::Insertion $t
  171.     }
  172. }
  173.  
  174. proc elec::MenuProc {menu item} {
  175.     switch $item {
  176.     "Next Stop Or Indent" {bind::IndentOrNextstop}
  177.     "Prev Stop" { ring::- }
  178.     "nth Stop" {ring::nth}
  179.     "Complete" {bind::Completion}
  180.     "Complete Or Tab" {bind::TabOrComplete}
  181.     "Expand" {bind::Expansion}
  182.     "Next Stop" {ring::+}
  183.     "Real Tab" {insertActualTab}
  184.     "Add Electric Item" {elec::AddItem}
  185.     "Grab Selection" {elec::GrabSelection}
  186.     "Insert Old Selection" {elec::InsertOldSelection}
  187.     "Insert In Lines" {elec::InsertInLines}
  188.     "Clear All Stops" {ring::clear}
  189.     "Clear Elec Menu Cache" {elec::clearAndBuildElectricMenu}
  190.     default {
  191.         if {[regexp {(.*) $} $item "" item]} {
  192.         set item [join $item ""]
  193.         elec::userTemplates $menu \
  194.           [string tolower [string index $item 0]][string range $item 1 end]
  195.         } else {
  196.         insertText $item
  197.         bind::Completion
  198.         }
  199.     }
  200.     }
  201. }
  202.  
  203. proc elec::AddItem {} {
  204.     global mode
  205.     if {$mode == ""} { beep ; message "No mode set…" ; return }
  206.     global ${mode}electrics
  207.     set e [prompt "Enter the electric item for '$mode' mode:" ""]
  208.     if {$e == ""} {return}
  209.     set default [file::_varValue ${mode}electrics($e)]
  210.     #[file::_getDefault "Do you want to start with this as the template?"]
  211.     set value [getline "Enter the electric extension, using •prompt•, \\r \\\{, \\\} etc" $default]
  212.     if {$value != ""} {
  213.     if {[string length $value] > 210} {
  214.         alertnote "Alpha unfortunately truncates direct entry to about 200 characters, however you can add directly to arrdefs.tcl"
  215.     }
  216.     eval set ${mode}electrics($e) \"$value\"
  217.     addArrDef ${mode}electrics $e [set ${mode}electrics($e)]
  218.     cache::deletePat elecMenu::elec-[modeALike]
  219.     elec::rebuildElectricMenu
  220.     }
  221. }
  222.  
  223. proc file::addTemplateItem {} {
  224.     global elec::MenuTemplates mode
  225.     global ${mode}Templates
  226.     set v elec::MenuTemplates
  227.     set v [expr {$mode != "" && [dialog::yesno \
  228.       "Is this item '$mode' mode-specific (otherwise I'll make it global)?"] \
  229.       ? "${mode}Templates" : "elec::MenuTemplates"}]
  230.     set e [join [prompt "Enter the new template menu item name:" ""] ""]
  231.     if {$e == ""} {return}
  232.     set e [string tolower [string index $e 0]][string range $e 1 end]
  233.     set default [file::_getDefault "Do you want to start with this as the template?" t]
  234.     set t "\r"
  235.     append t "proc file::${e} \{\} \{\r"
  236.     append t "\t# You must fill this in\r"
  237.     append t $default
  238.     append t "\r\r\telec::Insertion \$t\r\}\r"
  239.     addUserLine $t
  240.     lappend $v $e
  241.     lappend modifiedVars $v
  242.     elec::rebuildTemplatesMenu
  243.     regsub -all "\r" $default ";" default
  244.     append default { elec::Insertion $t}
  245.     ;proc file::$e {} $default
  246.     elec::clearAndBuildElectricMenu
  247.     if {[dialog::yesno "I've added a template for the procedure to your 'prefs.tcl'. Do you want to edit it now?"]} {
  248.     global::editPrefsFile
  249.     goto [maxPos]
  250.     }
  251.     return ""
  252. }
  253.  
  254. proc file::removeTemplateItem {} {
  255.     global elec::MenuTemplates mode
  256.     global ${mode}Templates
  257.     global modifiedVars
  258.     set tlist ${elec::MenuTemplates}
  259.     catch {set tlist [concat $tlist [set ${mode}Templates]]}
  260.     set l [listpick -p "Which template shall I permanently remove?" \
  261.       [lsort $tlist]]
  262.     if {[set i [lsearch ${elec::MenuTemplates} $l]] != -1} {
  263.         set elec::MenuTemplates [lreplace ${elec::MenuTemplates} $i $i]
  264.         lappend modifiedVars elec::MenuTemplates
  265.     } else {
  266.         set i [lsearch [set ${mode}Templates] $l]
  267.         set ${mode}Templates [lreplace [set ${mode}Templates] $i $i]
  268.         lappend modifiedVars ${mode}Templates
  269.     }
  270.     elec::rebuildTemplatesMenu
  271.     elec::clearAndBuildElectricMenu
  272.     global::editPrefsFile
  273.     set pat "\rproc\[ \t\]+file::"
  274.     append pat $l
  275.     append pat "\[ \t\]+\{\[ \t\]*\}\[ \t\]\{(\r\[^\}\].*)*\r\}\r"
  276.     while 1 {
  277.         set fpos [search -f 1 -r 1 -n $pat 0]
  278.         if {[string compare $fpos ""] == 0} {
  279.             break
  280.         }
  281.         deleteText [lindex $fpos 0] [lindex $fpos 1]
  282.     }
  283.     while 1 {
  284.         set fpos [search -f 1 -r 1 -n "^(\r\r|\n\n)" 0]
  285.         if {[string compare $fpos ""] == 0} {
  286.             break
  287.         }
  288.         replaceText [lindex $fpos 0] [lindex $fpos 1] "\r"
  289.     }
  290.     save
  291.     return ""
  292. }
  293.  
  294.  
  295. # procedures below get added to the menu if you set the 'poweruser' flag
  296. # in "elecBindings.tcl".  They make it easy to create large template 
  297. # procedures 
  298. proc elec::GrabSelection {} {
  299.     global __elec::grabbed
  300.     set __elec::grabbed [getSelect]
  301. }
  302.  
  303. proc elec::InsertOldSelection {} {
  304.     global __elec::grabbed
  305.     insertText [quote::Insert [set __elec::grabbed]]
  306. }
  307.  
  308. proc elec::InsertInLines {} {
  309.     global __elec::grabbed
  310.     insertText [elec::_MakeIntoInsertion ${__elec::grabbed}]
  311. }
  312.  
  313. proc elec::_MakeIntoInsertion {t {var "t"}} {
  314.     if {$t == ""} { return $t }
  315.     regsub -all "\n" $t "\r" t
  316.     while 1 {
  317.         set ret [string first "\r" $t]
  318.         if { $ret == -1 } { set ret [string length $t] }
  319.         append b [string range $t 0 $ret]
  320.         if {[string length $b] > 20} {
  321.             while 1 {
  322.                 append a "\tappend $var \"[quote::Insert [string range $b 0 59]]\"\r"
  323.                 if {[set b [string range $b 60 end]] == ""} {
  324.                     break
  325.                 }
  326.             }
  327.         }
  328.         set t [string range $t [incr ret] end]
  329.         if {[string length $t] == 0} { 
  330.             if {$b != ""} {
  331.                 append a "\tappend $var \"$b\"\r"
  332.             }
  333.             break 
  334.         }
  335.     }
  336.     return $a
  337. }
  338.  
  339.  
  340.  
  341.  
  342.